package com.yzdbx.individualtask;

import cn.hutool.core.collection.CollectionUtil;
import com.yzdbx.utils.DbUtil;
import com.yzdbx.utils.GenUtil;

import java.math.BigDecimal;
import java.sql.*;
import java.time.LocalDate;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

public class SaleOrderFaHuoReGen {
    /**
     * 生成销售发货数据（出库单，发货单，销售发货明细，）
     * @param args
     * @throws Exception
     */
    public static void main(String[] args) throws Exception {
        // 处理日期参数
        String startDate = null;
        String endDate = null;

//        String startDate = "2025-06-28";
//        String endDate = "2025-06-30";
        
        if (args.length >= 2) {
            startDate = args[0];
            endDate = args[1];
            System.out.println("指定生成日期范围: " + startDate + " 到 " + endDate);
        } else if (args.length == 1) {
            startDate = args[0];
            endDate = args[0];
            System.out.println("指定生成日期: " + startDate);
        } else {
            System.out.println("未指定日期，将生成所有销售订单的发货数据");
        }
        
        // 初始化 GenUtil 的日期信息
        LocalDate currentDate = LocalDate.now();
        if (startDate != null) {
            currentDate = LocalDate.parse(startDate);
        }
        GenUtil.setCurDate(currentDate);
        GenUtil.setCurTimeStamp(new Timestamp(currentDate.atStartOfDay(ZoneId.systemDefault()).toInstant().toEpochMilli()));
        
        Connection connection = DbUtil.getConnection();
        boolean originalAutoCommit = true;
        
        try {
            originalAutoCommit = connection.getAutoCommit();
            connection.setAutoCommit(false);

            // 查询销售订单ID（根据日期范围过滤）
            List<Integer> orderIds = new ArrayList<>();
            String orderQuery;
            PreparedStatement stmt;
            
            if (startDate != null && endDate != null) {
                if (startDate.equals(endDate)) {
                    // 单个日期
                    orderQuery = "SELECT id FROM salesOrders WHERE DATE(dateOfOrder) = ?";
                    stmt = connection.prepareStatement(orderQuery);
                    stmt.setString(1, startDate);
                } else {
                    // 日期范围
                    orderQuery = "SELECT id FROM salesOrders WHERE DATE(dateOfOrder) BETWEEN ? AND ?";
                    stmt = connection.prepareStatement(orderQuery);
                    stmt.setString(1, startDate);
                    stmt.setString(2, endDate);
                }
            } else {
                // 所有日期
                orderQuery = "SELECT id FROM salesOrders";
                stmt = connection.prepareStatement(orderQuery);
            }
            
            ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                orderIds.add(rs.getInt("id"));
            }
            rs.close();
            stmt.close();

            if (CollectionUtil.isEmpty(orderIds)) {
                if (startDate != null && endDate != null) {
                    if (startDate.equals(endDate)) {
                        System.out.println("没有找到 " + startDate + " 日期的销售订单数据，无法生成发货数据！");
                    } else {
                        System.out.println("没有找到 " + startDate + " 到 " + endDate + " 日期范围的销售订单数据，无法生成发货数据！");
                    }
                } else {
                    System.out.println("没有找到销售订单数据，无法生成发货数据！");
                }
                return;
            }

            List<Integer> fahuoIds = new ArrayList<>(orderIds.size());
            int batchCount = 0;
            
            // 按日期分组的出库单号计数器
            Map<String, Integer> ckDateCounterMap = new HashMap<>();
            final int BATCH_SIZE = 3;

            int fahuoMaxId = getMaxId(connection, "xs05SalesAndDispatch");
            int ckdId = getMaxId(connection, "lists");
            int maxDetailId = getMaxId(connection, "xssalesDispatchDetails");
            int ckmxId = getMaxId(connection, "ck02CheckoutFormCheckout");
            
            // 按日期分组的发货单号计数器
            Map<String, Integer> dateCounterMap = new HashMap<>();

            // 准备批量插入语句
            String detailSql = "insert into xssalesDispatchDetails (id,associatedConsignmentOrder,productInformation,quantityOfShipments,amountOfShipment,unitPriceForShipment,numberOfOrders,numberOfRemainingShipments,numberOfRefunds,amountOfReturn,synchronisingFolderFailedSS,modifyer) values (?,?,?,?,?,?,?,?,?,?,?,?)";
            String fahuoSql = "insert into xs05SalesAndDispatch (id,shipmentOrderNumber,dateOfShipment,shipper,associatedSalesOrders,clientInformation,quantityOfShipments,synchronisingFolderFailedSS,created,approvalStatus) values (?,?,?,?,?,?,?,?,?,?)";
            String ckmxSql = "insert into ck02CheckoutFormCheckout(id,productInformation,numberOfReleases,inventoryUnitPrice,numberOfDeposits,linkOutList,synchronisingFolderFailedSS,modifyer,created,modified) values (?,?,?,?,?,?,?,?,?,?)";
            String ckdSql = "insert into lists (id,cashiersNumber,poolType,collectionDate,operator,synchronisingFolderFailedSS,created,associatedOrders,clientInformation) values (?,?,?,?,?,?,?,?,?)";

            try (PreparedStatement detailStatement = connection.prepareStatement(detailSql);
                 PreparedStatement fahuoStatement = connection.prepareStatement(fahuoSql);
                 PreparedStatement ckmxStatement = connection.prepareStatement(ckmxSql);
                 PreparedStatement ckdStatement = connection.prepareStatement(ckdSql)) {

                for (int i = 1; i <= orderIds.size(); i++) {
                    final int currentIndex = i - 1;
                    int curId = fahuoMaxId + i;
                    
                    // 查询销售订单
                    Map<String, Object> saleOrder = DbUtil.getById(connection, "salesOrders", orderIds.get(currentIndex));
                    if (saleOrder == null) continue;
                    
                    // 获取销售订单的订单日期
                    java.sql.Date orderDate = (java.sql.Date) saleOrder.get("dateOfOrder");
                    Timestamp orderTimestamp = new Timestamp(orderDate.getTime());
                    
                    // 设置当前日期为订单日期，确保发货单号生成正确
                    GenUtil.setCurDate(orderDate.toLocalDate());
                    GenUtil.setCurTimeStamp(orderTimestamp);
                    
                    // 按日期分组的发货单号生成逻辑
                    String dateKey = orderDate.toString();
                    int currentCount = dateCounterMap.getOrDefault(dateKey, 0) + 1;
                    dateCounterMap.put(dateKey, currentCount);
                    String fahuodanhao = GenUtil.getNo("XSFH", currentCount);
                    
                    // 查询销售订单明细
                    List<LinkedHashMap<String, Object>> details;
                    try (PreparedStatement statement = connection.prepareStatement("select * from xs02SalesOrderBreakdown where associatedSalesOrders = ?")) {
                        statement.setInt(1, orderIds.get(currentIndex));
                        ResultSet resultSet = statement.executeQuery();
                        details = DbUtil.resultSetToList(resultSet);
                    }

                    List<LinkedHashMap<String, Object>> associatedSalesOrders = details.stream()
                            .filter(cur -> cur.get("associatedSalesOrders").equals(orderIds.get(currentIndex)))
                            .collect(Collectors.toList());

                    // 创建发货单详情
                    for (int j = 1; j <= associatedSalesOrders.size(); j++) {
                        int detailId = ++maxDetailId;
                        LinkedHashMap<String, Object> orderDetail = associatedSalesOrders.get(j - 1);
                        
                        detailStatement.setInt(1, detailId);
                        detailStatement.setInt(2, curId);
                        detailStatement.setInt(3, Integer.parseInt(orderDetail.get("productInformation").toString()));
                        detailStatement.setInt(4, Integer.parseInt(orderDetail.get("quantityOfShipments").toString()));
                        BigDecimal unitPrice = BigDecimal.valueOf(Double.parseDouble(orderDetail.get("unitPrice").toString()));
                        int quantity = Integer.parseInt(orderDetail.get("quantityOfShipments").toString());
                        detailStatement.setBigDecimal(5, unitPrice.multiply(BigDecimal.valueOf(quantity)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        detailStatement.setBigDecimal(6, unitPrice);
                        detailStatement.setInt(7, quantity);
                        detailStatement.setInt(8, 0);
                        detailStatement.setInt(9, 0);
                        detailStatement.setInt(10, 0);
                        detailStatement.setString(11, saleOrder.get("synchronisingFolderFailedSS").toString());
                        detailStatement.setString(12, saleOrder.get("synchronisingFolderFailedSS").toString());
                        detailStatement.addBatch();

                        // 创建出库明细
                        int curCkmxId = ++ckmxId;
                        ckmxStatement.setInt(1, curCkmxId);
                        ckmxStatement.setInt(2, Integer.parseInt(orderDetail.get("productInformation").toString()));
                        ckmxStatement.setInt(3, quantity);
                        ckmxStatement.setBigDecimal(4, unitPrice);
                        ckmxStatement.setBigDecimal(5, unitPrice.multiply(BigDecimal.valueOf(quantity)).setScale(2, BigDecimal.ROUND_HALF_UP));
                        ckmxStatement.setInt(6, ckdId + i);
                        ckmxStatement.setString(7, saleOrder.get("synchronisingFolderFailedSS").toString());
                        ckmxStatement.setString(8, saleOrder.get("synchronisingFolderFailedSS").toString());
                        ckmxStatement.setTimestamp(9, orderTimestamp);
                        ckmxStatement.setTimestamp(10, orderTimestamp);
                        ckmxStatement.addBatch();
                    }
                    
                    // 创建发货单
                    fahuoStatement.setInt(1, curId);
                    fahuoStatement.setString(2, fahuodanhao);
                    fahuoStatement.setTimestamp(3, orderTimestamp);
                    fahuoStatement.setString(4, saleOrder.get("synchronisingFolderFailedSS").toString());
                    fahuoStatement.setInt(5, orderIds.get(currentIndex));
                    fahuoStatement.setInt(6, Integer.parseInt(saleOrder.get("clientInformation").toString()));
                    fahuoStatement.setInt(7, Integer.parseInt(saleOrder.get("numberOfOrders").toString()));
                    fahuoStatement.setString(8, saleOrder.get("synchronisingFolderFailedSS").toString());
                    fahuoStatement.setTimestamp(9, orderTimestamp);
                    fahuoStatement.setString(10, "已通过");
                    fahuoStatement.addBatch();

                    // 按日期分组的出库单号生成逻辑
                    int ckCurrentCount = ckDateCounterMap.getOrDefault(dateKey, 0) + 1;
                    ckDateCounterMap.put(dateKey, ckCurrentCount);
                    
                    // 设置当前日期为订单日期，确保单号生成正确
                    GenUtil.setCurDate(orderDate.toLocalDate());
                    GenUtil.setCurTimeStamp(orderTimestamp);
                    
                    // 创建出库单
                    ckdStatement.setInt(1, ckdId + i);
                    ckdStatement.setString(2, GenUtil.getNo("CK", ckCurrentCount));
                    ckdStatement.setString(3, "销售出库");
                    ckdStatement.setTimestamp(4, orderTimestamp);
                    ckdStatement.setString(5, saleOrder.get("synchronisingFolderFailedSS").toString());
                    ckdStatement.setString(6, saleOrder.get("synchronisingFolderFailedSS").toString());
                    ckdStatement.setTimestamp(7, orderTimestamp);
                    ckdStatement.setInt(8, orderIds.get(currentIndex));
                    ckdStatement.setInt(9, Integer.parseInt(saleOrder.get("clientInformation").toString()));
                    ckdStatement.addBatch();

                    fahuoIds.add(curId);
                    batchCount++;

                    // 每BATCH_SIZE条记录执行一次批量插入
                    if (batchCount >= BATCH_SIZE) {
                        detailStatement.executeBatch();
                        fahuoStatement.executeBatch();
                        ckmxStatement.executeBatch();
                        ckdStatement.executeBatch();
                        connection.commit();
                        batchCount = 0;
                    }
                }

                // 执行剩余的批量插入
                if (batchCount > 0) {
                    detailStatement.executeBatch();
                    fahuoStatement.executeBatch();
                    ckmxStatement.executeBatch();
                    ckdStatement.executeBatch();
                    connection.commit();
                }
            }

            if (startDate != null && endDate != null) {
                if (startDate.equals(endDate)) {
                    System.out.println(startDate + " 日期的销售发货表数据生成完成！共生成 " + fahuoIds.size() + " 条发货记录");
                } else {
                    System.out.println(startDate + " 到 " + endDate + " 日期范围的销售发货表数据生成完成！共生成 " + fahuoIds.size() + " 条发货记录");
                }
            } else {
                System.out.println("销售发货表数据生成完成！共生成 " + fahuoIds.size() + " 条发货记录");
            }
            
        } finally {
            try {
                connection.setAutoCommit(originalAutoCommit);
            } catch (SQLException ignore) {}
            DbUtil.closeConnection(connection);
        }
    }

    private static int getMaxId(Connection connection, String table) throws SQLException {
        try (Statement stmt = connection.createStatement();
             ResultSet rs = stmt.executeQuery("SELECT MAX(id) FROM " + table)) {
            if (rs.next()) {
                return rs.getInt(1);
            }
        }
        return 0;
    }
} 